const webpack = require('webpack')
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
	VueLoaderPlugin
} = require('vue-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const projectBase = require('./build/project.base');
const fs = require('fs');


let lastStr = process.argv[process.argv.length - 1];
lastStr = lastStr.toLowerCase(); // 转化成小写
let paramArr = lastStr.split('=');
let moduleName = paramArr[paramArr.length - 1] || null; //模块名称
let isAlone = false;


let setEntry = function () {
	let obj = {};
	let all = {}; //全部模块
	let alone = {}; //单独模块
	for (let key in projectBase) {
		let item = projectBase[key];
		if (item.buildInstruct == moduleName) {
			alone[key] = path.resolve(`.${item.mainJsSrc}`);
			isAlone = true;
		}
		all[key] = path.resolve(`.${item.mainJsSrc}`);
	}
	obj = isAlone && alone || all;
	return obj;
}

let setHtmlPlugin = function () {
	let arr = [];
	let all = []; //全部模块
	let alone = []; //单独模块
	for (let key in projectBase) {
		let item = projectBase[key];
		let htmlObj = {
			template: path.resolve(`.${item.indexHtmlSrc}`),
			filename: `${key}/index.html`,
			chunks: [key],
			hash: true,
		}
		if (key == "index") {
			htmlObj.filename = "index.html";
			alone.push(new HtmlWebpackPlugin(htmlObj));
		}
		if (item.buildInstruct == moduleName) {
			alone.push(new HtmlWebpackPlugin(htmlObj));
		}
		all.push(new HtmlWebpackPlugin(htmlObj));
	}
	arr = isAlone && alone || all;
	return arr;
}


module.exports = {
	// 入口
	entry: {
		// index: __dirname + '/src/public/index.js',
		...setEntry(),
	},
	// 出口
	output: {
		// publicPath: './',
		path: path.resolve(__dirname, 'dist'),
		filename: '[name]/js/[name].[hash:8].bundle.js',
		chunkFilename: '[name].[chunkhash:8].chunk.js',
		// assetModuleFilename: '/images/[hash][ext][query]'
	},
	// 模块
	module: {
		rules: [{
			test: /\.(mjs|js|jsx)$/,
			exclude: /node_modules/, // 忽略第三方的代码
			include: /src/,
			use: {
				loader: 'babel-loader',
				options: {
					presets: ['@babel/preset-env', '@babel/preset-react']
				}
			}
		}, {
			test: /\.vue$/,
			use: {
				loader: 'vue-loader',
			},
		}, {
			test: /\.css$/,
			use: [
				// 'style-loader',
				MiniCssExtractPlugin.loader,
				'css-loader'
			],
			include: [
				path.resolve(__dirname, 'src')
			],
		}, {
			test: /\.scss$/,
			use: [
				// 'style-loader',
				MiniCssExtractPlugin.loader,
				'css-loader',
				'sass-loader'
			],
			include: [
				path.resolve(__dirname, 'src')
			],
		}, {
			// test: /\.(png|jpg|gif)$/i,
			test: /\.(png|jpg|gif|jpeg)$/,
			exclude: /node_modules/,
			use: [{
				loader: 'url-loader',
				// loader: 'file-loader',
				options: {
					limit: 8 * 1024, // 8K， 图片大于limit，使用file-loader模块进行加载；否则编译成base64字符串形式
					name: 'assets/img/[name].[hash:7].[ext]',
					esModule: false,
					// context: path.resolve(__dirname, '../../img'),
					// outputPath: './img',
					// publicPath: './img',
				},
			}],
			type: 'javascript/auto',
		}],
	},
	resolve: {
		extensions: ['.js', '.vue', '.json'],
		alias: {
			'@': path.resolve('src'),
			'@admin': path.resolve('src/modules/admin'),
			'@mall': path.resolve('src/modules/mall'),
			'@news': path.resolve('src/modules/news'),
		}
	},
	// 插件
	plugins: [
		new VueLoaderPlugin(),
		// new HtmlWebpackPlugin({
		// 	template: __dirname + '/src/public/index.html',
		// 	filename: 'index.html',
		// 	chunks: ['index'],
		// 	hash: true,
		// }),
		...setHtmlPlugin(),
		new MiniCssExtractPlugin({
			filename: '[name]/css/[hash:7].style.css', // 对css文件重命名
		}),
	],
}



/**
 * 监听webpack打包结束
 */
const outputPath = __dirname + '/dist';
let timer = null;
try {
	let watcher = fs.watch(outputPath, {
		recursive: true, // recursive: true 表示监听目录下的所有子目录
	}, (event, filename) => {
		if (filename && event == 'change') {
			clearTimeout(timer);
			timer = setTimeout(() => {
				// console.log(`文件全部更新完成`)
				watcher.close();
				// transferFile();
			}, 1000)
		}
	});
} catch (e) {
	//TODO handle the exception
}



/**
 * 移动文件
 */
async function transferFile() {
	const files = fs.readdirSync(`${__dirname}/dist/assets/img`);
	console.log(files)
	for (let p in projectBase) {
		for (let f of files) {
			if (f.indexOf(p + '-') != -1) {
				let exist = false;
				try {
					exist = await dirExists(`${__dirname}/dist/${p}/assets/`);
				} catch (e) {
					//TODO handle the exception
				}
				if (exist) {
					// 复制图片 方法一
					try {
						// var readStream = fs.createReadStream(`${__dirname}/dist/assets/img/${f}`); // 被复制文件
						// var writeStream = fs.createWriteStream(`${__dirname}/dist/${p}/${f}`); // 复制到的目标位置及文件
						// readStream.pipe(writeStream);
						// 复制图片 方法二
						// fs.writeFileSync(`${__dirname}/dist/${p}/${f}`, fs.readFileSync(`${__dirname}/dist/assets/img/${f}`));	
					} catch (e) {
						//TODO handle the exception
					}

					// 移动图片 
					try {
						var fileName = f;
						var sourceFile = path.join(`${__dirname}/dist/assets/img/`, fileName);
						var destPath = path.join(`${__dirname}`, `/dist/${p}/assets/`, fileName);
						fs.rename(sourceFile, destPath, function (err) {
							if (err) {
								// throw err;
								// console.log(err)
							};
							fs.stat(destPath, function (err, stats) {
								if (err) {
									// throw err;
									// console.log(err)
								};
								// console.log('stats: ' + JSON.stringify(stats));
							});
						});
					} catch (e) {
						//TODO handle the exception
					}
				}
			}
		}
	}
}


/**
 * 读取路径信息
 * @param {string} path 路径
 */
function getStat(path) {
	return new Promise((resolve, reject) => {
		fs.stat(path, (err, stats) => {
			if (err) {
				resolve(false);
			} else {
				resolve(stats);
			}
		})
	})
}

/**
 * 创建路径
 * @param {string} dir 路径
 */
function mkdir(dir) {
	return new Promise((resolve, reject) => {
		fs.mkdir(dir, err => {
			if (err) {
				resolve(false);
			} else {
				resolve(true);
			}
		})
	})
}

/**
 * 路径是否存在，不存在则创建
 * @param {string} dir 路径
 */
async function dirExists(dir) {
	let isExists = await getStat(dir);
	//如果该路径且不是文件，返回true
	if (isExists && isExists.isDirectory()) {
		return true;
	} else if (isExists) { //如果该路径存在但是文件，返回false
		return false;
	}
	//如果该路径不存在
	let tempDir = path.parse(dir).dir; //拿到上级路径
	//递归判断，如果上级目录也不存在，则会代码会在此处继续循环执行，直到目录存在
	let status = await dirExists(tempDir);
	let mkdirStatus;
	if (status) {
		mkdirStatus = await mkdir(dir);
	}
	return mkdirStatus;
}
